﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace Day5
{
    class Program
    {
        static void Main(string[] args)
        {
            // demo1();
            // demo2();
            demo3();
        }

        #region demo1
        /// <summary>
        /// 死锁
        /// </summary>
        private static void demo1()
        {
            Task task1 = Task.Factory.StartNew(() =>
            {
                Console.WriteLine("Task 1 running");
                while (true)
                {
                    Thread.Sleep(1000);
                }
                Console.WriteLine("Task 1 finished");
            });
            Task task2 = Task.Factory.StartNew(() =>
            {
                Console.WriteLine("Task 2 running");
                Thread.Sleep(2000);
                Console.WriteLine("Task 2 finished");
            });
            Task.WaitAll(task1, task2);
            Console.ReadLine();
        }
        #endregion

        #region demo2
        /// <summary>
        /// 死锁的时候的处理
        /// 我们可以设置最大等待时间，如果超过了等待时间，
        /// 就不再等待，下面我们来修改代码，设置最大等待时间为5秒
        /// (项目中可以根据实际情况设置)，如果超过5秒就输出哪个任务出错了
        /// </summary>
        private static void demo2()
        {
            Task[] tasks = new Task[2];
            tasks[0] = Task.Factory.StartNew(() =>
            {
                Console.WriteLine("Task 1 start running");
                while (true)
                {
                    Thread.Sleep(1000);
                }
                Console.WriteLine("Task 1 finished");
            });
            tasks[1] = Task.Factory.StartNew(() =>
            {
                Console.WriteLine("Task 2 start running");
                Thread.Sleep(2000);
                Console.WriteLine("Task 2 finished");
            });
            Task.WaitAll(tasks, 5000);
            for(int i = 0; i < tasks.Length; i++)
            {
                if (tasks[i].Status != TaskStatus.RanToCompletion)
                {
                    Console.WriteLine($"Task {i + 1} error!");
                }
            }
            Console.ReadLine();
        }
        #endregion

        #region demo3
        /// <summary>
        /// SpinLock(自旋锁)
        /// </summary>
        private static void demo3()
        {
            SpinLock spinLock = new SpinLock(false);
            long sum1 = 0;
            long sum2 = 0;
            Parallel.For(0, 100000, (i) =>
            {
                sum1 += i;
            });

            Parallel.For(0, 100000, (i) =>
            {
                bool lockToken = false;
                try
                {
                    spinLock.Enter(ref lockToken);
                    sum2 += i;
                }
                finally
                {
                    if (lockToken)
                    {
                        spinLock.Exit(false);
                    }
                }
            });
            Console.WriteLine($"sum1的值为:{sum1}");
            Console.WriteLine($"sum2的值为:{sum2}");
            Console.ReadLine();
        }
        #endregion
    }
}
